let l = 78 :: 12 :: 43 :: 52 :: [];;

let print_bool b = print_string (string_of_bool b);;

let print_size l =
  print_endline (string_of_int (List.length l))
;;

let rec print_list l =
  match l with
    | hd :: tl -> print_int hd; print_char ' '; print_list tl;
    | [] -> print_newline ();
;;

let rec print_assoc l =
  let f (x, y) =
    print_char '('; print_int x; print_string ", "; print_int y; print_char ')';
  in
    List.iter f l;
    print_newline ();
;;

print_string "l = ";;
print_list l;;

print_string "length l = ";;
print_size l;;

print_string "l @ l = ";;
print_list (l @ l);;

print_string "hd l = ";;
print_int (List.hd l);;
print_newline ();;

print_string "tl l = ";;
print_list (List.tl l);;

print_string "nth l 2 = ";;
print_int (List.nth l 2);;
print_newline ();;

print_string "rev l = ";;
print_list (List.rev l);;

print_string "flatten [ l ; rev l ; l ] = ";;
print_list (List.flatten [ l ; List.rev l ; l ]);;

print_string "map succ l = ";;
print_list (List.map succ l);;

print_string "rev_map pred l = ";;
print_list (List.rev_map pred l);;

print_string "iter print_int l = ";;
List.iter print_int l;;
print_newline ();;

print_string "fold_left (-) 0 l = ";;
print_int (List.fold_left (-) 0 l);;
print_newline ();;

print_string "fold_right (-) l 0 = ";;
print_int (List.fold_right (-) l 0);;
print_newline ();;

print_string "map2 (+) l l = ";;
print_list (List.map2 (+) l l);;

print_string "rev_map2 (+) l l = ";;
print_list (List.rev_map2 (+) l l);;

print_string "iter2 (print +) l (rev l) = ";;
List.iter2 (fun x y -> print_int (x + y); print_char ' ') l (List.rev l);;
print_newline ();;

print_string "fold_left2 (fun : acc + (y - x)) l (rev l) = ";;
print_int (List.fold_left2 (fun acc x y -> acc + (y - x)) 0 l (List.rev l));;
print_newline ();;

print_string "fold_right2 (fun : acc + (y - x)) l (rev l) = ";;
print_int (List.fold_right2 (fun x y acc -> acc + (y - x)) l (List.rev l) 0);;
print_newline ();;

print_string "for_all ((<>) 52) l = ";;
print_bool (List.for_all ((<>) 52) l);;
print_newline ();;

print_string "exists ((=) 12) l = ";;
print_bool (List.exists ((=) 12) l);;
print_newline ();;

print_string "for_all2 (=) l l = ";;
print_bool (List.for_all2 (=) l l);;
print_newline ();;

print_string "exists2 (=) l (rev l) = ";;
print_bool (List.exists2 (=) l (List.rev l));;
print_newline ();;

print_string "mem 52 l = ";;
print_bool (List.mem 52 l);;
print_newline ();;

print_string "memq 53 l = ";;
print_bool (List.mem 53 l);;
print_newline ();;

print_string "assoc 31 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ] = ";;
print_int (List.assoc 31 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ]);;
print_newline ();;

print_string "assq 4 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ] = ";;
print_int (List.assq 4 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ]);;
print_newline ();;

print_string "mem_assoc 5 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ] = ";;
print_bool (List.mem_assoc 5 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ]);;
print_newline ();;

print_string "mem_assq 31 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ] = ";;
print_bool (List.mem_assq 31 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ]);;
print_newline ();;

print_string "remove_assoc 31 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ] = ";;
print_assoc (List.remove_assoc 31 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ]);;

print_string "remove_assq 1 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ] = ";;
print_assoc (List.remove_assq 1 [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ]);;

print_string "find (fun x -> x mod 2 = 1) l = ";;
print_int (List.find (fun x -> x mod 2 = 1) l);;
print_newline ();;

print_string "find_all (fun x -> x mod 2 = 0) l = ";;
print_list (List.find_all (fun x -> x mod 2 = 0) l);;

print_string "partition (fun x -> x mod 3 = 0) l =";;
let (l1, l2) = List.partition (fun x -> x mod 3 = 0) l in
  print_newline (); print_list l1; print_list l2;;

print_string "split [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ] = ";;
let (l1, l2) = List.split [ (1, 2) ; (31, 66) ; (4, 5) ; (31, 88) ] in
  print_newline (); print_list l1; print_list l2;;

print_string "combine [ 1 ; 3 ; 5 ; 7 ] [ 2 ; 4 ; 6 ; 8 ] = ";;
print_assoc (List.combine [ 1 ; 3 ; 5 ; 7 ] [ 2 ; 4 ; 6 ; 8 ]);;

print_string "merge compare [ 1 ; 3 ; 5 ] [ 2 ; 4 ; 6 ; 8 ; 10 ] = ";;
print_list (List.merge compare [ 1 ; 3 ; 5 ] [ 2 ; 4 ; 6 ; 8 ; 10 ]);;

print_string "sort compare [ 1 ; 9 ; 1 ; 8 ; 5 ; 6 ; 2 ; 0 ] = ";;
print_list (List.sort compare [ 1 ; 9 ; 1 ; 8 ; 5 ; 6 ; 2 ; 0 ]);;
